#include "renderer.h"
#include <stdio.h>


Renderer::Renderer(Puzzle *p, int w, int h)
{
    this->wc = p->wc;
    //worldX = worldY = worldZ = 0;
    this->scene = p->getBricks();
    this->hero = p->getBallPos();

    this->w = w;
    this->h = h;
    set3DProjection();
}

void Renderer::set2DProjection()
{
    glDisable(GL_DEPTH_TEST);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(0, w, 0, h);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity(); 
}

void Renderer::set3DProjection()
{
    float ex = wc[0] / 2.0f + scene[0].pos[0]/2.0;
    float ey =  wc[1] /2.0f +  scene[0].pos[1]/2.0 ; 
    float ez =  5 + (wc[2]>wc[0]? (wc[2] > wc[1]? wc[2] : wc[1]) : (wc[0] > wc[1]? wc[0] : wc[1]));
    
    glClearColor(0, 0, 0, 0);
    glViewport(0, 0, w, h);
    glEnable(GL_DEPTH_TEST);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(90, (float)w/(float)h, 0.01f, 100.0f);
    //glOrtho(-1, ez, -1, ez, -ez, ez);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(ex, ey, ez, ex, ey, -ez, 0, 1, 0);
}

void Renderer::getWorldDims(float *vals)
{
    vals[0] = wc[0];
    vals[1] = wc[1];
    vals[2] = wc[2];
}
void Renderer::drawCube(float x, float y, float z, float size = 1.0)
{

    GLfloat vertices[] = {size/2, size/2, size/2, -size/2, size/2, size/2, -size/2, -size/2, size/2, size/2, -size/2, size/2,
                             size/2, size/2, -size/2, -size/2, size/2, -size/2, -size/2, -size/2, -size/2, size/2, -size/2, -size/2,
                             size/2, size/2, size/2, size/2, -size/2, size/2, size/2, -size/2, -size/2, size/2, size/2, -size/2,
                             -size/2, -size/2, size/2, -size/2, -size/2, -size/2, size/2, -size/2, -size/2, size/2, -size/2, size/2,
                             -size/2, size/2, size/2, size/2, size/2, size/2, size/2, size/2, -size/2, -size/2, size/2, -size/2,
                             -size/2, size/2, -size/2, -size/2, -size/2, -size/2, -size/2, -size/2, size/2, -size/2, size/2, size/2};

    GLfloat texels[] = { 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0,
                                1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0,
                                1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0,
                                1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0,
                                1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0,
                                1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0,
                                1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0,
                                1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 };

   glEnableClientState(GL_VERTEX_ARRAY);
   glEnableClientState(GL_TEXTURE_COORD_ARRAY);

   glVertexPointer(3, GL_FLOAT, 0, vertices);
   glTexCoordPointer(2, GL_FLOAT, 0, texels);
   glPushMatrix();
   glTranslatef(x, y, z);
   //glColor4f(0.2f, 0.5f, 1.0f, 1.0f);
   glDrawArrays(GL_QUADS, 0, 24);
   glPopMatrix();
   glDisableClientState(GL_VERTEX_ARRAY);
   glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}

void Renderer::renderScene()
{
    int i = 0;
    bool done = false;
    glColor3f(1, 1, 1);
    glDisable(GL_TEXTURE_2D);
    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    float size = (wc[2]>wc[0]? (wc[2] > wc[1]? wc[2] : wc[1]) : (wc[0] > wc[1]? wc[0] : wc[1]));
    drawCube(size/2, size/2, size/2, size+1);
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    glEnable(GL_TEXTURE_2D);
    glColor3f(1, 0, 0);
    glPushMatrix();
    drawCube(hero[0], hero[1], hero[2]);
    glPopMatrix();
    glColor3f(1, 1, 1);
    while(!done)
    {
        if(scene[i].isFinal)
        {
            done = true;
            glColor3f(0, 1, 0);
        }
        glPushMatrix();
        drawCube(scene[i].pos[0], scene[i].pos[1], scene[i].pos[2]);
        glPopMatrix();
        i++;
    }
}

Renderer::~Renderer()
{
}
